package general.guicontrols.layoutmanager;

import general.art.Node;
import general.art.WeightedCenteredCluster;
import general.guicontrols.clusterpanels.MouseOverDisplay;
import general.guicontrols.clusterpanels.NodePanel;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;


public class CircularLayout implements LayoutManager {

	//ArrayList components;
	//ArrayList names;
	private WeightedCenteredCluster c;

	private boolean isCircle;
	//private Map<Component, Node> nToC;

	double rotation_offset;
	
	private final Map<Node, NodePanel> nodeToNodePanel;
	private final Map<Node, MouseOverDisplay> nodeToCircularDisplay;

	/**
	 * Creates a new CircleLayout that lays out components in a perfect circle
	 */
	public CircularLayout(WeightedCenteredCluster cc, Map<Node, NodePanel> nodeToComp,  Map<Node, MouseOverDisplay> nToc) {

		this(cc, nodeToComp, nToc, true);

	}

	/**
	 * Creates a new CircleLayout that lays out components in either an Ellipse or
	 * a Circle. Ellipse Layout is not yet implemented.
	 * 
	 * @param circle
	 *          Indicated the shape to use. It's true for circle or false for
	 *          ellipse.
	 */
	public CircularLayout(WeightedCenteredCluster cc, Map<Node, NodePanel> nTop, Map<Node, MouseOverDisplay> nToC,   boolean circle) {

		isCircle = circle;
		c = cc;
		nodeToNodePanel = nTop;
		nodeToCircularDisplay = nToC;
		rotation_offset = 0;
	}

	/**
	 * For compatibility with LayoutManager interface
	 */
	public void addLayoutComponent(String name, Component comp) {

		//nodeToCircularDisplay.put(Node.)

	}

	/**
	 * Arranges the parent's Component objects in either an Ellipse or a Circle.
	 * Ellipse is not yet implemented.
	 */
	public void layoutContainer(final Container parent) {
		int x, y, w, h, s, c;
		int n = nodeToNodePanel.size();
		double parentWidth = parent.getSize().width;
		double parentHeight = parent.getSize().height;
		Insets insets = parent.getInsets();
		int centerX = (int) (parentWidth - (insets.left + insets.right)) / 2;
		int centerY = (int) (parentHeight - (insets.top + insets.bottom)) / 2;

		Component comp = null;
		Component bComp = null;
		Dimension compPS = null;
		if (n == 1) {
			comp = parent.getComponent(0);
			x = centerX;
			y = centerY;
			compPS = comp.getPreferredSize();
			w = compPS.width;
			h = compPS.height;
			comp.setBounds(x, y, w, h);
		} else {
			double r = (Math.min(parentWidth - (insets.left + insets.right), parentHeight
					- (insets.top + insets.bottom))) / 2;
			r *= 0.75; // Multiply by .75 to account for extreme right and bottom
			// Components

			int i = 0;
			for(Node  node  : this.c.getNodes()){

				comp = nodeToNodePanel.get(node);
				bComp = nodeToCircularDisplay.get(node);
				//node  = nToC.get(comp);

				//System.out.println(bComp + " " + comp);
				
				//double new_r = r - 0.5*r*this.c.getWeight(node)/maxweight;
				double new_r = r;	
				double ii = i+rotation_offset;
				if(comp != null){

					compPS = comp.getPreferredSize();
					if (isCircle) {
						c = (int) (new_r * Math.cos(2 * ii * Math.PI / n));
						s = (int) (new_r * Math.sin(2 * ii * Math.PI / n));
					} else {
						c = (int) ((centerX * 0.75) * Math.cos(2 * ii * Math.PI / n));
						s = (int) ((centerY * 0.75) * Math.sin(2 * ii * Math.PI / n));
					}
					x = c*2 + centerX;
					y = s + centerY;

					w = compPS.width;
					h = compPS.height;

					comp.setBounds(x, y, w, h);
					if(bComp != null){
				
						bComp.setBounds(x -300,y -150, 600, 300);

					}
				}

				i++;

			}
			if(rotation_offset >= n)
			{
				rotation_offset = 0;
			}
			rotation_offset += 0.01;
			
		}

	}

	/**
	 * Returns this CircleLayout's preferred size based on its Container
	 * 
	 * @param target
	 *          This CircleLayout's target container
	 * @return The preferred size
	 */
	public Dimension preferredLayoutSize(Container target) {
		return target.getSize();
	}

	/**
	 * Returns this CircleLayout's minimum size based on its Container
	 * 
	 * @param target
	 *          This CircleLayout's target container
	 * @return The minimum size
	 */
	public Dimension minimumLayoutSize(Container target) {
		return target.getSize();
	}

	/**
	 * For compatibility with LayoutManager interface
	 */
	public void removeLayoutComponent(Component comp) {
	}

	/**
	 * Returns a String representation of this CircleLayout.
	 * 
	 * @return A String that represents this CircleLayout
	 */
	public String toString() {
		return this.getClass().getName();
	}

}